package UMC.Web;

import UMC.Data.Utility;

import java.util.UUID;

public abstract class WebHandler {

    public WebContext context() {
        return _context;
    }

    WebContext _context;

    /**
     * 指令对话框
     *
     * @param asyncId 值ID
     * @param model
     * @param cmd
     * @return
     */
    public String asyncDialog(String asyncId, String model, String cmd) {
        return this.asyncDialog(asyncId, model, cmd, new WebMeta());

    }

    public String asyncDialog(String asyncId, String model, String cmd, boolean isSafe) {
        return this.asyncDialog(asyncId, model, cmd, new WebMeta(), isSafe, 0);

    }

    public String asyncDialog(String asyncId, String model, String cmd, int timeout) {
        return this.asyncDialog(asyncId, model, cmd, new WebMeta(), timeout > 0, timeout);

    }

    /**
     * 指令对话框
     *
     * @param asyncId 值ID
     * @param model
     * @param cmd
     * @param meta
     * @return
     */
    public String asyncDialog(String asyncId, String model, String cmd, WebMeta meta) {
        return this.asyncDialog(asyncId, g -> {
            WebMeta webMeta = new WebMeta();
            String id = UMC.Data.Utility.uuid(UUID.randomUUID());
            webMeta.put("Key", id);
            webMeta.put("Name", asyncId);
            webMeta.put("Click", new WebMeta().put("model", model, "cmd", cmd).put("send", meta.put("Key", id)));
            webMeta.put("Submit", new WebMeta("model", this._context.runtime.request._model, "cmd",
                    this._context.runtime.request._cmd).put("send", this._context.runtime.request.Arguments));
            this._context.runtime.response.Headers.put("UIEvent", webMeta);
            this._context.runtime.response.ClientEvent = this._context.runtime.response.ClientEvent | WebEvent.UIEvent;
            this._context.runtime.response.end();
            return this.dialogValue("none");
        });

    }

    public String asyncDialog(String asyncId, String model, String cmd, WebMeta meta, int timeout) {
        return this.asyncDialog(asyncId, model, cmd, meta, timeout > 0, timeout);

    }

    public String asyncDialog(String asyncId, String model, String cmd, WebMeta meta, boolean isSafe) {
        return this.asyncDialog(asyncId, model, cmd, meta, isSafe, 0);
    }

    private static String eventKey = UUID.randomUUID().toString();

    /**
     * 指令对话框
     * 
     * @param asyncId
     * @param model
     * @param cmd
     * @param meta
     * @param isSafe  安全模式
     * @return
     */
    private String asyncDialog(String asyncId, String model, String cmd, WebMeta meta, boolean isSafe, int timeout) {
        if (isSafe) {
            String value = this.asyncDialog(asyncId, model, cmd, meta);

            String sign = this.asyncDialog("KEY_DIALOG_SIGN",
                    r -> this.dialogValue((System.currentTimeMillis() / 1000) + ","));
            String nonce = sign.substring(0, sign.indexOf(','));
            if (timeout > 0) {
                if (Utility.parse(nonce, 0) + timeout < (System.currentTimeMillis() / 1000)) {
                    sign = (System.currentTimeMillis() / 1000) + ",";
                }
            }
            String sn = Utility.uuid(Utility.uuid(asyncId + eventKey + nonce + value, true));
            if (!sign.contains(sn)) {
                if (_context.runtime.client.RedirectTimes >= 2) {
                    if (sign.length() == 1) {
                        _context.runtime.request.Arguments.put("KEY_DIALOG_SIGN", sn);
                    } else {
                        _context.runtime.request.Arguments.put("KEY_DIALOG_SIGN", sign + "," + sn);
                    }
                } else {
                    _context.runtime.request.Arguments.remove(asyncId);
                    WebMeta v = _context.runtime.request.sendValues();
                    if (v != null) {
                        v.remove(asyncId);
                    }
                    _context.runtime.request._Headers.remove(asyncId);
                    meta.put("CheckValue", value);
                    return this.asyncDialog(asyncId, model, cmd, meta);
                }

            }
            return value;

        }
        return this.asyncDialog(asyncId, model, cmd, meta);

    }

    /**
     * 单值对话框
     *
     * @param callback
     * @param asyncId
     * @return
     */
    public String asyncDialog(String asyncId, UIDialog.Callback callback) {

        return UIDialog.asyncDialog(_context, asyncId, callback);
    }

    /**
     * 多值对话框
     *
     * @param callback
     * @param asyncId
     * @return
     */
    public WebMeta asyncDialog(UIDialog.CallForm callback, String asyncId) {

        return UIDialog.asyncDialog(asyncId, _context, callback);
    }

    /**
     * 单值对话框
     *
     * @param asyncId 值ID
     * @param deValue 默认值
     * @return
     */
    protected String asyncDialog(String asyncId, String deValue) {
        return asyncDialog(asyncId, a -> dialogValue(deValue));

    }

    /**
     * 用于对方模型返回单值内容
     */

    protected UIDialog dialogValue(String value) {
        return UIDialog.returnValue(value);
    }

    /**
     * 用于对方模型返回多值内容
     */

    protected UIFormDialog dialogValue(WebMeta value) {
        return UIDialog.returnValue(value);
    }

    /**
     * 提示
     *
     * @param text 提示内容
     */

    protected void prompt(String text) {

        prompt(text, true);
    }

    /**
     * 提示
     *
     * @param title 提示标题
     * @param text  提示内容
     */
    protected void prompt(String title, String text) {
        this.prompt(title, text, true);
    }

    /**
     * 提示
     *
     * @param text        提示内容
     * @param endResponse 是否终止
     */

    protected void prompt(String text, boolean endResponse) {
        WebResponse response = _context.response();
        response.ClientEvent |= WebEvent.PROMPT;

        response.Headers.put("Prompt", new WebMeta().put("Text", text));
        if (endResponse) {
            _context.end();
        }

    }

    /**
     * 提示
     *
     * @param title       提示标题
     * @param text        提示内容
     * @param endResponse 是否终止
     */

    protected void prompt(String title, String text, boolean endResponse) {

        WebResponse response = _context.response();
        response.ClientEvent |= WebEvent.ASYNCDIALOG;// | WebClient.Prompt;
        WebMeta prompt = new WebMeta();
        prompt.put("Text", text).put("Title", title).put("Type", "Prompt");// = text;

        response.Headers.put("AsyncDialog", prompt);
        if (endResponse) {
            _context.end();
        }

    }
}
